/*
 * Author: Le Truong
 * Email: travistrle@gmail.com
 * Date: 15DEC2013
 */

package vn.buffalocoders.rikos.ui.login;

import java.util.Map;

import org.json.JSONArray;

import com.sromku.simple.fb.Properties;
import com.sromku.simple.fb.SimpleFacebook;
import com.sromku.simple.fb.SimpleFacebook.OnLoginListener;
import com.sromku.simple.fb.SimpleFacebook.OnProfileRequestListener;
import com.sromku.simple.fb.entities.Profile;

import vn.buffalocoders.rikos.R;
import vn.buffalocoders.rikos.ui.category.CategoryActivity;
import vn.buffalocoders.rikos.ui.common.FacebookApplication;
import vn.buffalocoders.rikos.ui.common.Helper;
import vn.buffalocoders.rikos.ui.common.sessions.SessionManager;
import vn.buffalocoders.rikos.ui.network.ConnectRikoServer;
import vn.buffalocoders.rikos.ui.network.NetworkUtil;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Rect;

import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewTreeObserver;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;


public class LogInActivity extends Activity  implements OnClickListener{

	// Rikos Login Variable
	private UserLoginTask mAuthTask = null;
	private String TAG = "LETRUONG_TEST_FACEBOOK";
	// Reference to UI Object
	private TextView mValidateText;
	private EditText mEmailView;
	private EditText mPasswordView;
	private ProgressDialog progress;
	private RelativeLayout root;
	// Session Manager Variable
	SessionManager session;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_log_in);
		
		// User Session
		session = new SessionManager(LogInActivity.this); 
		
		// Set up reference to UI Object
		mValidateText = (TextView) findViewById(R.id.validate_text);
		mEmailView = (EditText) findViewById(R.id.emailTxt);
		mPasswordView = (EditText) findViewById(R.id.passwordTxt);
		root = (RelativeLayout) findViewById(R.id.login_controls_form);
		
		// Disable Validate Text
		mValidateText.setVisibility(TextView.INVISIBLE);
		
		// Initialize Progress Dialog
		progress = new ProgressDialog(this);
		
		// Capture click event
		findViewById(R.id.fbLogInBtn).setOnClickListener(this);
		findViewById(R.id.loginBtn).setOnClickListener(this);
		findViewById(R.id.fbLogInBtn).setOnClickListener(this);
		findViewById(R.id.footerFbLogin).setOnClickListener(this);
		
		// Capture Soft-KeyBoard visible / disable
		// Based on http://stackoverflow.com/questions/2150078/how-to-check-
		// visibility-of-software-keyboard-in-android. Compare the size of the screen
		// with the size of the root view's getWindowVisibleDisplayFrame. If they're
		// very different, assume it's because the soft keyboard is showing.
		root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
			  @Override public void onGlobalLayout() {
			    Rect r = new Rect();
			    //r will be populated with the coordinates of your view that area still visible.
			    root.getWindowVisibleDisplayFrame(r);
			 
			    int screenHeight = root.getRootView().getHeight();
			    int heightDiff = screenHeight - (r.bottom - r.top);
			    boolean visible = heightDiff > screenHeight / 3;
			 
			    if (visible) {
			    	Log.i("LETRUONG", "Keyboard visible");
			    	// Animation
			    	root.setBackgroundColor(Color.parseColor("#aa000000"));
			    }
			    else {
			    	Log.i("LETRUONG", "Keyboard invisible");
			    	root.setBackgroundColor(Color.parseColor("#00ffffff"));
			    }
			  }
			});
	}

	@Override
	public void onResume()
	{
	    super.onResume();
	    ((FacebookApplication) getApplication()).setSimpleFacebook(SimpleFacebook.getInstance(this));
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		((FacebookApplication) getApplication()).getSimpleFacebook().onActivityResult(this, requestCode, resultCode, data);
		super.onActivityResult(requestCode, resultCode, data);
	}
	
	@Override
	public void onClick(View v) {
		if(v.getId() == R.id.loginBtn) {
			attempteLogin();
		}
		else if (v.getId() == R.id.footerFbLogin || v.getId() == R.id.fbLogInBtn) {
			((FacebookApplication) getApplication()).getSimpleFacebook().login(mOnLoginListener);
		}
	}
	
	/**
	 * Facebook Login Listener from Simple Facebook Lib
	 */
	private OnLoginListener mOnLoginListener = new OnLoginListener()
	{

		@Override
		public void onFail(String reason)
		{

		}

		@Override
		public void onException(Throwable throwable)
		{
			
		}

		@Override
		public void onThinking()
		{
			// show progress bar or something to the user while login is happening

		}

		@Override
		public void onLogin()
		{
			Properties properties = new Properties.Builder()
			    .add(Properties.ID)
			    .add(Properties.NAME)
			    .add(Properties.EMAIL)
			    .add(Properties.PICTURE)
			    .build();

			// do the get profile action
			((FacebookApplication) getApplication()).getSimpleFacebook().getProfile(properties, onProfileRequestListener);
		}

		@Override
		public void onNotAcceptingPermissions()
		{
			
		}
	};

	/**
	 * Facebook Profile Request Listener from Simple Facebook Lib
	 */
	OnProfileRequestListener onProfileRequestListener = new SimpleFacebook.OnProfileRequestListener()
	{

	    @Override
	    public void onFail(String reason)
	    {
	        // insure that you are logged in before getting the profile
	        Log.w(TAG, reason);
	    }

	    @Override
	    public void onException(Throwable throwable)
	    {
	        Log.e(TAG, "Bad thing happened", throwable);
	    }

	    @Override
	    public void onThinking()
	    {
	        // show progress bar or something to the user while fetching profile
	        Log.i(TAG, "Thinking...");
	    }

	    @Override
	    public void onComplete(Profile profile)
	    {
	        String _fbName = profile.getName();
	        String _email = profile.getEmail();
	        String _avatar = profile.getPicture();
	        //String _period_token;
	        double _period_token = ((FacebookApplication) getApplication()).getSimpleFacebook().getOpenSession().getExpirationDate().getTime();
	        String _fb_id = profile.getId();
	        String _fb_access_token = ((FacebookApplication) getApplication()).getSimpleFacebook().getAccessToken();
	        Log.i(TAG, String.format("_fb_name=%s, _email=%s, _avatar=%s, _period_token=%s, _fb_id=%s, _access_token",
	        		_fbName, _email, _avatar, Double.toString(_period_token), _fb_id, _fb_access_token));
	        new UserFbLoginTask().execute(_fbName, _email, _avatar, Double.toString(_period_token), _fb_id, _fb_access_token, null, null, null);
	    }
	};
	
	
    /**
     * Represents an asynchronous login/registration task used to authenticate the user
     */
    public class UserLoginTask extends AsyncTask<Object /* Param */, Void /* Progress */, Map<String, String> /* Result */> {

		@Override
		protected Map<String, String> doInBackground(Object... params) {
			// TODO Auto-generated method stub
			return ConnectRikoServer.loginWithRikoServer((String)params[0], (String)params[1]);
		}
    	
		@Override
		protected void onPostExecute(final Map<String, String> result) {
			mAuthTask = null;
			
			if (result == null) {
				// Validate or Network error
				Log.i("LETRUONG", "onPostExecute=null");
				mValidateText.setVisibility(View.VISIBLE);
				mValidateText.setText(getResources().getString(R.string.error_connection_with_rikos));
			}
			else {
				if (result.get(ConnectRikoServer.RIKO_RESULT_STATUS).equals(ConnectRikoServer.RIKO_STATUS_SUCCESS)) {
					Log.i("LETRUONG", "result=success");
					Intent intent = new Intent(LogInActivity.this, CategoryActivity.class);
					Log.i("LETRUONG", String.format("login_activity,user_id=%s,auth_token=%s", result.get(ConnectRikoServer.RIKO_RESULT_USER_ID), result.get(ConnectRikoServer.RIKO_RESULT_AUTH_TOKEN)));
					session.createLoginSession(result.get(ConnectRikoServer.RIKO_RESULT_NAME), result.get(ConnectRikoServer.RIKO_RESULT_EMAIL), 
												result.get(ConnectRikoServer.RIKO_RESULT_PASSWORD), result.get(ConnectRikoServer.RIKO_RESULT_AUTH_TOKEN), 
												result.get(ConnectRikoServer.RIKO_RESULT_USER_ID), result.get(ConnectRikoServer.RIKO_RESULT_AVATAR));
					intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
					// on your logout method:
					Intent broadcastIntent = new Intent();
					broadcastIntent.setAction("com.package.ACTION_LOGOUT");
					sendBroadcast(broadcastIntent);
					startActivity(intent);
					finish();
				}
				else if (result.get(ConnectRikoServer.RIKO_RESULT_STATUS).equals(ConnectRikoServer.RIKO_STATUS_FAILED)) {
					Log.i("LETRUONG", "result=failure");
					hideProgress();
					mValidateText.setVisibility(View.VISIBLE);
					mValidateText.setText(result.get(ConnectRikoServer.RIKO_RESULT_CAUSE));
				}
			}
		}
		
		@Override
		protected void onCancelled() {
			mAuthTask = null;
		}
    }
    
    public class UserFbLoginTask extends AsyncTask<Object /* Param */, Void /* Progress */, Map<String, String> /* Result */> {

		@Override
		protected Map<String, String> doInBackground(Object... params) {
			// TODO Auto-generated method stub
			return ConnectRikoServer.loginFacebookWithRikoServer((String)params[0], (String)params[1], (String)params[2],
					(String)params[3], (String)params[4], (String)params[5], (JSONArray)params[6], (String)params[7], (String)params[8]);
		}
    	
		@Override
		protected void onPostExecute(final Map<String, String> result) {
			mAuthTask = null;
			
			if (result == null) {
				// Validate or Network error
				hideProgress();
				mValidateText.setVisibility(View.VISIBLE);
				mValidateText.setText(getResources().getString(R.string.error_connection_with_rikos));
			}
			else {
				if (result.get(ConnectRikoServer.RIKO_RESULT_STATUS).equals(ConnectRikoServer.RIKO_STATUS_SUCCESS)) {
					Log.i("LETRUONG", "result=success");
					Intent intent = new Intent(LogInActivity.this, CategoryActivity.class);

					Log.i("LETRUONG", String.format("login_activity,user_id=%s,auth_token=%s", result.get(ConnectRikoServer.RIKO_RESULT_USER_ID), result.get(ConnectRikoServer.RIKO_RESULT_AUTH_TOKEN)));
					session.createLoginSession(result.get(ConnectRikoServer.RIKO_RESULT_NAME), result.get(ConnectRikoServer.RIKO_RESULT_EMAIL), 
												result.get(ConnectRikoServer.RIKO_RESULT_PASSWORD), result.get(ConnectRikoServer.RIKO_RESULT_AUTH_TOKEN), 
												result.get(ConnectRikoServer.RIKO_RESULT_USER_ID), result.get(ConnectRikoServer.RIKO_RESULT_AVATAR));
					startActivity(intent);
					finish();
				}
				else if (result.get(ConnectRikoServer.RIKO_RESULT_STATUS).equals(ConnectRikoServer.RIKO_STATUS_FAILED)) {
					Log.i("LETRUONG", "LogIActivity=result=failure");
					hideProgress();
					mValidateText.setVisibility(View.VISIBLE);
					mValidateText.setText(result.get(ConnectRikoServer.RIKO_RESULT_CAUSE));
				}
			}
		}
		
		@Override
		protected void onCancelled() {
			mAuthTask = null;
		}
    }
    /**
	 * Attempts to sign in or register the account specified by the login form
	 * If there are form errors (invalid email, missing fields, etc.), the
	 * errors are presented and no actual login attempt is made
	 */
	public void attempteLogin() {
		if (mAuthTask != null) {
			return;
		}
		
		if (!Helper.validateForLogInActivity(getApplicationContext(), mValidateText, mEmailView, mPasswordView)) {
			return;
		}
		
		// Check Internet Connection
		if (NetworkUtil.getConnectivityStatus(LogInActivity.this) == NetworkUtil.TYPE_NOT_CONNECTED) {
			mValidateText.setVisibility(View.VISIBLE);
			mValidateText.setText(getResources().getString(R.string.error_connection_with_rikos));
			return;
		}
		
		showProgress();
		// Send login to Server
		mAuthTask = new UserLoginTask();
		mAuthTask.execute(mEmailView.getText().toString(), mPasswordView.getText().toString());
	}
	
	/**
	 * Common functions
	 */
	private void showProgress() {
		progress.setMessage(String.format("%s.......", getResources().getString(R.string.status_login)));
	    progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
	    progress.setIndeterminate(true);
	    progress.show();
	}
	
	public void hideProgress() {
		Log.i("LETRUONG", "progress dismiss");
		progress.dismiss();
	}
}